package goescape

import "errors"

// Slice of escape codes.
type Escapes []Escape

// Create and return Escapes containing sets.
func New(sets ...Escape) Escapes {
	return new(Escapes).Append(sets...)
}

// Return a copy of sets with newSets appended at position n.
func (sets Escapes) AppendN(n int, newSets ...Escape) Escapes {
	return append(append(append(Escapes{}, sets[:n]...), newSets...), sets[n:]...)
}

// Return a copy of sets with newSets appended.
func (sets Escapes) Append(newSets ...Escape) Escapes {
	return sets.AppendN(len(sets), newSets...)
}

// Return a copy of sets.
func (sets Escapes) Copy() Escapes {
	return sets.Append()
}

// Return a copy of sets with the set deleted at position n.
func (sets Escapes) DeleteN(n int) Escapes {
	return append(append(Escapes{}, sets[:n]...), sets[n+1:]...)
}

// Return a copy of sets with oldSets deleted.
func (sets Escapes) Delete(oldSets ...Escape) (newSets Escapes) {
	newSets = sets.Copy()

	for _, oldSet := range oldSets {
		for n := 0; n < len(newSets); n++ {
			if newSets[n] == oldSet {
				newSets = append(newSets[:n], newSets[n+1:]...)
				break
			}
		}
	}

	return
}

// Return a copy of sets with all oldSets deleted.
func (sets Escapes) DeleteAll(oldSets ...Escape) (newSets Escapes) {
	newSets = sets.Copy()

	for _, oldSet := range oldSets {
		for n := 0; n < len(newSets); {
			if newSets[n] == oldSet {
				newSets = append(newSets[:n], newSets[n+1:]...)
			} else {
				n++
			}
		}
	}

	return
}

// Return sets converted to error.
func (sets Escapes) Error() error {
	return errors.New(sets.String())
}

// Return sets converted to Escape.
func (sets Escapes) Escape() (sum Escape) {
	for _, set := range sets {
		sum += set
	}

	return
}

// Compare sets and targetSets.
func (sets Escapes) Is(targetSets Escapes) bool {
	if len(sets) != len(targetSets) {
		return false
	}

	for i := 0; i < len(sets); i++ {
		if sets[i] != targetSets[i] {
			return false
		}
	}

	return true
}

// Return sets converted to string.
func (sets Escapes) String() (sum string) {
	for _, set := range sets {
		sum += set.String()
	}

	return
}
